Skip to content

fix(install.sh): Windows-from-bash works end-to-end (#94 Tailscale, #98 DefaultShell, AIRC_CHANNEL)#192

Merged
joelteply merged 4 commits intocanaryfrom
fix/install-honor-airc-channel-on-fresh
Apr 28, 2026
Merged

fix(install.sh): Windows-from-bash works end-to-end (#94 Tailscale, #98 DefaultShell, AIRC_CHANNEL)#192
joelteply merged 4 commits intocanaryfrom
fix/install-honor-airc-channel-on-fresh

Conversation

@joelteply
Copy link
Copy Markdown
Contributor

@joelteply joelteply commented Apr 28, 2026

Joel 2026-04-28: "is anyone running claude or codex from inside powershell?" — no. Users are in Git Bash via Claude Code / Codex on Windows. We were forcing them to switch shells just to install. Bad onboarding, and onboarding is what determines whether users stay or bail.

This PR makes `bash install.sh` on Git Bash (MSYS) the canonical Windows install path. install.ps1 stays around for users who specifically want `airc.ps1` (PowerShell-native), but Git Bash / Claude Code / Codex users no longer need to touch PowerShell.

What's in here

  1. AIRC_CHANNEL honored on fresh install (vhsm-d1f4's catch). `AIRC_CHANNEL=canary curl|bash` now lands on canary instead of silently dropping to main. `git clone --branch $CHANNEL_TARGET`, validates against {main, canary}, persists to `.channel` for future updates.

  2. DefaultShell registry write (bug: install.ps1 — DefaultShell unconfigured; Windows airc message delivery fails (cmd.exe lacks 'cat') #98). The MSYS elevated PowerShell payload now also writes `HKLM:\SOFTWARE\OpenSSH\DefaultShell` to Git for Windows `bash.exe`. Without this, every Windows airc HOST silently fails inbound `airc msg` because OpenSSH's default shell is cmd.exe.

  3. Tailscale via winget on MSYS (bug: install.ps1 — Tailscale winget package ID typo (lowercase) causes silent install failure #94). `install_tailscale` gains a MINGW branch using `winget install --id Tailscale.Tailscale` (proper case).

Result

Single command from any shell on Windows:

```
AIRC_CHANNEL=canary bash -c "$(curl -fsSL https://raw.githubusercontent.com/CambrianTech/airc/canary/install.sh)\"
```

Does the full Windows host setup — winget prereqs + Tailscale + sshd capability + HNS port-22 reservation + firewall rule + sshd start + DefaultShell=bash — in one shot. One UAC prompt for the elevated sshd payload. No PowerShell shell switching.

Test plan

  • AIRC_CHANNEL=canary verified locally — lands on canary, writes .channel
  • AIRC_CHANNEL unset verified locally — defaults to main, writes .channel=main
  • AIRC_CHANNEL=bogus verified locally — warns + falls back to main
  • Windows fresh-install verification (Joel doing this, the actual gate)

🤖 Generated with Claude Code

Caught by vhsm-d1f4 2026-04-28 during the #191 release-gate fresh-
install verification: \`AIRC_CHANNEL=canary curl|bash\` silently landed
on main, requiring a follow-up \`airc canary && airc update\` dance.

The fresh-install branch (line 495 pre-fix) was \`git clone\` without
specifying a branch, so it defaulted to the repo's default (main)
regardless of the env var. The update-existing branch already honored
\$SAVED_CHANNEL via \$CLONE_DIR/.channel; only the cold-start path was
broken.

Fix:
1. \$CHANNEL_TARGET = \${AIRC_CHANNEL:-main}, validated against the
   known list (main, canary) — unknown values fall back to main with
   a warning rather than failing later with an obscure git error.
2. \`git clone --branch \$CHANNEL_TARGET\` lands directly on the
   requested branch.
3. Write \$CLONE_DIR/.channel after clone so future \`airc update\`
   stays on the same channel (matches what \`airc canary\` / \`airc
   main\` would write).

Verified locally: AIRC_CHANNEL=canary lands on canary HEAD; default
lands on main; bogus value falls back to main with the warning.
Copilot AI review requested due to automatic review settings April 28, 2026 03:30
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the install.sh first-install path to respect the requested release channel (e.g., canary) so fresh installs land on the intended branch and persist that choice for future updates.

Changes:

  • On first install, select a channel target from AIRC_CHANNEL (default main) and validate it against known channels.
  • Clone the repo using git clone --branch <channel> so the checkout lands on the desired branch immediately.
  • Persist the chosen channel to $CLONE_DIR/.channel to keep subsequent airc update aligned.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread install.sh
Comment on lines +496 to +498
# First install. Honor AIRC_CHANNEL if set so users can land on canary
# directly via `AIRC_CHANNEL=canary curl|bash` without a follow-up
# `airc canary && airc update` dance. Default to main (the release
…l ask)

Joel 2026-04-28: "is anyone running claude or codex from inside
powershell?" — basically nobody. Real users are in Git Bash via
Claude Code / Codex on Windows, and we were forcing them to switch
shells just to install. Bad onboarding.

install.sh on MSYS already covered most of the Windows setup (winget
prereqs, OpenSSH.Server capability, HNS port-22, firewall, sshd
start). Two gaps closed here:

1. **DefaultShell registry write** (#98). The elevated PowerShell
   payload now also writes HKLM:\SOFTWARE\OpenSSH\DefaultShell to
   Git for Windows bash.exe. Without this, every Windows airc HOST
   silently fails inbound `airc msg` because OpenSSH's default shell
   is cmd.exe, which lacks `cat`, POSIX redirects, and the rest of
   the vocabulary airc remote commands assume. Bash candidates +
   PATH lookup + idempotent registry write.

2. **Tailscale via winget** (#94). install_tailscale's case statement
   now has an MSYS branch using `winget install --id Tailscale.Tailscale`
   (proper case — winget --exact is case-sensitive). Previously
   install.sh on Git Bash skipped Tailscale entirely.

Result: a Windows user pasting

    AIRC_CHANNEL=canary bash -c "$(curl -fsSL https://raw.githubusercontent.com/CambrianTech/airc/canary/install.sh)"

into their Git Bash terminal gets the FULL Windows host setup in one
shot — winget prereqs + Tailscale + sshd + DefaultShell — without
ever opening a PowerShell window. One UAC prompt for the elevated
sshd payload, that's it.

install.ps1 stays for the edge case where someone wants airc.ps1
(PowerShell-native) — that path still installs pwsh + wires
airc.cmd / airc.ps1 to %USERPROFILE%\AppData\Local\Programs\airc,
which bash install.sh deliberately does not (Git Bash users use the
bash airc via ~/.local/bin).
@joelteply joelteply changed the title fix(install.sh): honor AIRC_CHANNEL on fresh install (vhsm's catch) fix(install.sh): Windows-from-bash works end-to-end (#94 Tailscale, #98 DefaultShell, AIRC_CHANNEL) Apr 28, 2026
…s Git Bash)

Joel 2026-04-28: \"is anyone running claude or codex from inside
powershell?\" — basically nobody. Real users on Windows are in Git Bash
via Claude Code / Codex / Cursor / opencode / Windsurf / openclaw.
Pointing them at install.ps1 and 'open PowerShell' was bad onboarding
that we have to get perfect or we get no users.

Demote install.ps1 to a side note for the rare native-PowerShell user
who specifically wants airc.ps1. Lead with bash install.sh as the
universal entry point. The companion install.sh changes (in this same
PR) make MSYS path bulletproof: winget prereqs + Tailscale + sshd
capability + HNS port-22 + firewall + DefaultShell=bash.exe, all
behind one UAC prompt.

Two install sections updated (top, and the Setup block at line 120).
Skills already used the bash form everywhere so no skill changes needed.
Copilot AI review requested due to automatic review settings April 28, 2026 03:46
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the installation flow to make install.sh the canonical Windows install path when running from Git Bash (MSYS), aligning onboarding with Claude Code / Codex usage patterns and closing key Windows-host gaps (channel selection, OpenSSH DefaultShell, Tailscale install).

Changes:

  • Honor AIRC_CHANNEL on first install by cloning the requested branch (main/canary) and persisting it to .channel.
  • Extend Windows (Git Bash) sshd setup to also configure OpenSSH DefaultShell to Git Bash bash.exe.
  • Add a Windows Git Bash (MSYS) winget path for optional Tailscale install using the canonical Tailscale.Tailscale ID.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
install.sh Adds Windows Git Bash support improvements: DefaultShell registry write, winget-based Tailscale install branch, and AIRC_CHANNEL-aware first clone.
README.md Updates docs to position install.sh as the primary install command for all platforms including Windows Git Bash, with install.ps1 as an alternative for native PowerShell users.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread install.sh
Start-Service sshd;
Set-Service -Name sshd -StartupType Automatic;
Write-Host "airc: sshd ready (capability + HNS + firewall + service auto-start)";
$bashCandidates = @("C:\Program Files\Git\bin\bash.exe", "C:\Program Files (x86)\Git\bin\bash.exe", "$env:USERPROFILE\AppData\Local\Programs\Git\bin\bash.exe");
…there when it just got installed

Joel 2026-04-28: 'Cross lan mesh? tailscale is optional but recommended.
Well guess fucking what it is installed sooooo. fail?'

The end-of-install banner unconditionally printed 'Tailscale is optional
but recommended: https://tailscale.com' even after winget had just
installed it 30 seconds earlier. Reads as 'install failed' to the user.

Three states now handled:
- Not installed → show the optional/URL line (was always shown)
- Installed, logged out → ts_post_check warns + shows sign-in path
- Installed, logged in → silent (best UX)

Plus extend ts_post_check + tailscale_present to find Tailscale on
Windows Git Bash (`/c/Program Files/Tailscale/tailscale.exe`) — winget
installs there, PATH may not include it in the current shell yet, so
the bare `command -v tailscale` would have returned false and the post
install would have nagged users to install something already installed.
@joelteply joelteply merged commit 116bdef into canary Apr 28, 2026
6 checks passed
@joelteply joelteply deleted the fix/install-honor-airc-channel-on-fresh branch April 28, 2026 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants